package secret

import (
	"fmt"

	"gitee.com/micro-plat/sas/sas/modules/const/enum"
	"gitee.com/micro-plat/sas/sas/modules/const/models"
	per "gitee.com/micro-plat/sas/sas/modules/util/permission"

	"github.com/micro-plat/lib4go/errs"
	"github.com/micro-plat/lib4go/types"
)

//CertSecret 对象
type CertSecret struct {
	db *DBSecret
}

//NewCertSecret 创建对象
func NewCertSecret() *CertSecret {
	return &CertSecret{
		db: NewDBSecret(),
	}
}

//Generate Cert密钥生成
func (s *CertSecret) Generate(euid string, item *models.Item) (res *CertResponse, err error) {

	uid, err := s.generateCheck(euid)
	if err != nil {
		return
	}

	if uid == "" {
		//数据不存在时创建新数据并添加Cert密钥
		uid, err = s.db.addCertSecret(euid, item)
	} else {
		//数据存在时在原数据上添加Cert密钥
		err = s.db.updateCertSecret(uid, item)
	}
	if err != nil {
		return
	}

	info, err := s.db.GetPermission(euid)
	if err != nil {
		return
	}

	deleteCache(euid)
	return buildCertResponse(info)
}

func (s *CertSecret) generateCheck(euid string) (uid string, err error) {

	info, err := s.db.GetPermission(euid)
	if err != nil || len(info) == 0 {
		return
	}

	//密钥已存在
	if info.GetString(enum.GetNameByValue(enum.Cert)) != "" {
		err = errs.NewError(enum.ERR_ExistsSecret, fmt.Errorf("要生成的密钥已存在，若要修改该类型密钥请调用set或reset服务"))
		return
	}

	//密钥不存在，获取uid
	uid = info.GetString("uid")
	return
}

//Get Cert密钥获取
func (s *CertSecret) Get(euid string) (res *CertResponse, err error) {

	//获取数据
	info, err := GetSecretCache(euid)
	if err != nil {
		return
	}

	//构造返回参数
	return buildCertResponse(info)
}

//Reset Cert密钥重置
func (s *CertSecret) Reset(euid string, item *models.Item) (res *CertResponse, err error) {

	//获取数据
	info, err := s.existCheck(euid, enum.Cert)
	if err != nil {
		return
	}
	//保存密钥
	uid := info.GetString("uid")
	if err := s.db.updateCertSecret(uid, item); err != nil {
		return nil, err
	}

	//构造返回参数
	deleteCache(euid)
	return s.Get(euid)
}

func (s *CertSecret) existCheck(euid string, sType int) (info types.XMap, err error) {

	info, err = s.db.GetPermission(euid)
	if err != nil {
		return
	}

	//不存在数据
	if info == nil {
		err = errs.NewError(enum.ERR_NotExits, fmt.Errorf("数据不存在"))
		return
	}

	//密钥不存在
	if info.GetString(enum.GetNameByValue(sType)) == "" {
		err = errs.NewError(enum.ERR_NotExitsSecretType, fmt.Errorf("该类型密钥不存在"))
		return
	}

	return
}

//Enable Cert密钥启用
func (s *CertSecret) Enable(euid string) (res *CertResponse, err error) {

	//获取数据
	info, err := s.existCheck(euid, enum.Cert)
	if err != nil {
		return
	}

	//Cert密钥启用
	uid := info.GetString("uid")
	if !per.Check(info.GetInt("status"), enum.Cert) {
		if err := s.db.enableSecret(uid, enum.Cert); err != nil {
			return nil, err
		}
	}

	//构造返回参数
	deleteCache(euid)

	return s.Get(euid)
}

//Disable Cert密钥禁用
func (s *CertSecret) Disable(euid string) (res *CertResponse, err error) {

	//获取数据
	info, err := s.existCheck(euid, enum.Cert)
	if err != nil {
		return
	}

	//Cert密钥禁用
	uid := info.GetString("uid")
	if per.Check(info.GetInt("status"), enum.Cert) {
		if err := s.db.disableSecret(uid, enum.Cert); err != nil {
			return nil, err
		}
	}

	//构造返回参数
	deleteCache(euid)
	return s.Get(euid)
}

//Set Cert密钥设置
func (s *CertSecret) Set(euid string, item *models.Item) (res *CertResponse, err error) {

	//获取数据
	info, err := s.existCheck(euid, enum.Cert)
	if err != nil {
		return
	}
	//保存密钥
	uid := info.GetString("uid")
	if err := s.db.updateCertSecret(uid, item); err != nil {
		return nil, err
	}
	//构造返回参数
	deleteCache(euid)
	return s.Get(euid)
}
